package com.rengwuxian.coursecoroutines._1_basics

import android.os.Bundle
import android.widget.TextView
import androidx.activity.ComponentActivity
import androidx.lifecycle.lifecycleScope
import com.rengwuxian.coursecoroutines.R
import com.rengwuxian.coursecoroutines.common.Contributor
import com.rengwuxian.coursecoroutines.common.gitHub
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

/**
 * 挂起函数的性能优势：从withContext()说起
 * withContext()、suspend 关键字
 *
 * 挂起函数在系统设计层面/语法层面，相对于线程的方案有什么性能优势？ --》 哪些代码需要抽入到挂起函数中不纠结。
 * withContext()要不要一起封进挂起函数里？ 要，业务代码和withContext() 注定是绑在一起的，因为一开始就能确定任务是不是耗时任务。（语法层面优势）
 *
 * withContext()切线程，如果有不必须切的场景，会有额外的切线程性能损耗吗？没有，协程对这块有针对性的优化，当ContinuationInterceptor还是原来那个时，就不会真的去切线程，而是保持当前线程。
 * -- 系统性能优势，保证不会在主线程执行。
 *
 * 让函数的使用者需要注意的事项，变成了函数的作者，就不会出错，会永远在正确的线程执行。
 *
 * 传统的线程受语法特性限制，无法做到。
 *
 */
class WithContext2Activity : ComponentActivity() {
  private lateinit var infoTextView: TextView

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.layout_1)
    infoTextView = findViewById(R.id.infoTextView)

    CoroutineScope(Dispatchers.Main).launch {
      val data = getData()
      val processedData = processData(data)
      println("Processed data: $processedData")
    }
  }

  private suspend fun getData() = withContext(Dispatchers.IO) {
    // 网络代码
    "data"
  }

  private suspend fun processData(data: String) = withContext(Dispatchers.Default) {
    // 处理数据
    "processed $data"
  }

  private fun coroutinesStyle() = lifecycleScope.launch {
    val contributors = contributorsOfRetrofit()
    showContributors(contributors)
  }

  private suspend fun contributorsOfRetrofit() = gitHub.contributors("square", "retrofit")

  private fun showContributors(contributors: List<Contributor>) = contributors
    .map { "${it.login} (${it.contributions})" }
    .reduce { acc, s -> "$acc\n$s" }
    .let { infoTextView.text = it }
}